package main

import (
	"fmt"
	"log"
	"sync"
)

// 任务管理器
type DeployManager struct {
	jobMutex       sync.RWMutex
	deployWorkList map[string]deployer
	stopWorkList   map[string]deployer
}

// 初始化任务
func NewDeployManager(args ...deployer) *DeployManager {
	var deployl = make(map[string]deployer, len(args))
	for _, i := range args {
		deployl[i.name()] = i
		fmt.Printf("加载任务")
	}
	return &DeployManager{
		deployWorkList: deployl,
	}
}

// 任务更新
func (d *DeployManager) WorkUpdate(updateWorks map[string]deployer) {
	d.stopWorkList = make(map[string]deployer)
	d.jobMutex.Lock()
	defer d.jobMutex.Unlock()
	// 增量更新map，以新map为准，和老map对比
	// 在老map中遍历，判断新的map中是否有，有就保留，没有就去掉
	for workName, _ := range d.deployWorkList {
		if _, ok := updateWorks[workName]; !ok {
			// 在新map中没有，移入删除map
			d.stopWorkList[workName] = d.deployWorkList[workName]
			delete(d.deployWorkList, workName)
		}
	}
	for _, stopwork := range d.stopWorkList {
		ret := stopwork.stop(d)
		fmt.Println(ret)
	}
	// 在新map中遍历，判断老的map中是否没有，没有就添加
	for workName, _ := range updateWorks {
		if _, ok := d.deployWorkList[workName]; !ok {
			d.deployWorkList[workName] = updateWorks[workName]
		}
	}
}

type deployer interface {
	name() string
	deploy(dm *DeployManager) string
	stop(dm *DeployManager) string
}

type k8sDeploy struct {
	deployName   string
	detailParams []string
}

type nodeDeploy struct {
	deployName   string
	detailParams []string
}

func (d *DeployManager) WorkStart() {
	for _, startwork := range d.deployWorkList {
		ret := startwork.deploy(d)
		fmt.Println(ret)
	}
}

func (d *DeployManager) WorkStop() {
	for _, startwork := range d.stopWorkList {
		ret := startwork.stop(d)
		fmt.Println(ret)
	}
}

func (k *k8sDeploy) deploy(dm *DeployManager) string {
	log.Printf("%s k8s deploy task start deploy\n", k.name())
	delete(dm.deployWorkList, k.name())
	return fmt.Sprintf("%s,start success", k.name())
}

func (k *k8sDeploy) stop(dm *DeployManager) string {
	log.Printf("%s k8s deploy task stop deploy", k.name())
	return fmt.Sprintf("%s, stop success", k.name())
}

func (k *k8sDeploy) name() string {
	return k.deployName
}

// 执行完成任务后需要删除
func (n *nodeDeploy) deploy(dm *DeployManager) string {
	log.Printf("%s k8s deploy task start deploy", n.name())
	delete(dm.deployWorkList, n.name())
	return fmt.Sprintf("%s,start success", n.name())

}

func (n *nodeDeploy) stop(dm *DeployManager) string {
	log.Printf("%s k8s deploy task stop deploy", n.name())
	return fmt.Sprintf("%s, stop success", n.name())
}

func (n *nodeDeploy) name() string {
	return n.deployName
}

func main() {

	var kwork1 = &k8sDeploy{
		deployName:   "kwork1",
		detailParams: []string{"karg1", "karg2"},
	}

	var nwork1 = &nodeDeploy{
		deployName:   "nwork1",
		detailParams: []string{"narg1", "narg2"},
	}

	// 初始化开始放两个部署任务
	DeployManager := NewDeployManager(kwork1, nwork1)

	// 增量更新
	var kwork2 = &k8sDeploy{
		deployName:   "kwork2",
		detailParams: []string{"karg1", "karg2"},
	}

	var nwork2 = &nodeDeploy{
		deployName:   "nwork2",
		detailParams: []string{"narg1", "narg2"},
	}

	var updateworks = make(map[string]deployer)

	updateworks[kwork2.name()] = kwork2
	updateworks[nwork2.name()] = nwork2
	updateworks[kwork1.name()] = kwork1
	// 去掉 nwork1
	DeployManager.WorkUpdate(updateworks)
	DeployManager.WorkStart()
}
